<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Test Report</title>
    <link href="assets/style.css" rel="stylesheet" type="text/css"/></head>
  <body onLoad="init()">
    <script>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


function toArray(iter) {
    if (iter === null) {
        return null;
    }
    return Array.prototype.slice.call(iter);
}

function find(selector, elem) { // eslint-disable-line no-redeclare
    if (!elem) {
        elem = document;
    }
    return elem.querySelector(selector);
}

function findAll(selector, elem) {
    if (!elem) {
        elem = document;
    }
    return toArray(elem.querySelectorAll(selector));
}

function sortColumn(elem) {
    toggleSortStates(elem);
    const colIndex = toArray(elem.parentNode.childNodes).indexOf(elem);
    let key;
    if (elem.classList.contains('result')) {
        key = keyResult;
    } else if (elem.classList.contains('links')) {
        key = keyLink;
    } else {
        key = keyAlpha;
    }
    sortTable(elem, key(colIndex));
}

function showAllExtras() { // eslint-disable-line no-unused-vars
    findAll('.col-result').forEach(showExtras);
}

function hideAllExtras() { // eslint-disable-line no-unused-vars
    findAll('.col-result').forEach(hideExtras);
}

function showExtras(colresultElem) {
    const extras = colresultElem.parentNode.nextElementSibling;
    const expandcollapse = colresultElem.firstElementChild;
    extras.classList.remove('collapsed');
    expandcollapse.classList.remove('expander');
    expandcollapse.classList.add('collapser');
}

function hideExtras(colresultElem) {
    const extras = colresultElem.parentNode.nextElementSibling;
    const expandcollapse = colresultElem.firstElementChild;
    extras.classList.add('collapsed');
    expandcollapse.classList.remove('collapser');
    expandcollapse.classList.add('expander');
}

function showFilters() {
    const filterItems = document.getElementsByClassName('filter');
    for (let i = 0; i < filterItems.length; i++)
        filterItems[i].hidden = false;
}

function addCollapse() {
    // Add links for show/hide all
    const resulttable = find('table#results-table');
    const showhideall = document.createElement('p');
    showhideall.innerHTML = '<a href="javascript:showAllExtras()">Show all details</a> / ' +
                            '<a href="javascript:hideAllExtras()">Hide all details</a>';
    resulttable.parentElement.insertBefore(showhideall, resulttable);

    // Add show/hide link to each result
    findAll('.col-result').forEach(function(elem) {
        const collapsed = getQueryParameter('collapsed') || 'Passed';
        const extras = elem.parentNode.nextElementSibling;
        const expandcollapse = document.createElement('span');
        if (extras.classList.contains('collapsed')) {
            expandcollapse.classList.add('expander');
        } else if (collapsed.includes(elem.innerHTML)) {
            extras.classList.add('collapsed');
            expandcollapse.classList.add('expander');
        } else {
            expandcollapse.classList.add('collapser');
        }
        elem.appendChild(expandcollapse);

        elem.addEventListener('click', function(event) {
            if (event.currentTarget.parentNode.nextElementSibling.classList.contains('collapsed')) {
                showExtras(event.currentTarget);
            } else {
                hideExtras(event.currentTarget);
            }
        });
    });
}

function getQueryParameter(name) {
    const match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

function init () { // eslint-disable-line no-unused-vars
    resetSortHeaders();

    addCollapse();

    showFilters();

    sortColumn(find('.initial-sort'));

    findAll('.sortable').forEach(function(elem) {
        elem.addEventListener('click',
            function() {
                sortColumn(elem);
            }, false);
    });
}

function sortTable(clicked, keyFunc) {
    const rows = findAll('.results-table-row');
    const reversed = !clicked.classList.contains('asc');
    const sortedRows = sort(rows, keyFunc, reversed);
    /* Whole table is removed here because browsers acts much slower
     * when appending existing elements.
     */
    const thead = document.getElementById('results-table-head');
    document.getElementById('results-table').remove();
    const parent = document.createElement('table');
    parent.id = 'results-table';
    parent.appendChild(thead);
    sortedRows.forEach(function(elem) {
        parent.appendChild(elem);
    });
    document.getElementsByTagName('BODY')[0].appendChild(parent);
}

function sort(items, keyFunc, reversed) {
    const sortArray = items.map(function(item, i) {
        return [keyFunc(item), i];
    });

    sortArray.sort(function(a, b) {
        const keyA = a[0];
        const keyB = b[0];

        if (keyA == keyB) return 0;

        if (reversed) {
            return keyA < keyB ? 1 : -1;
        } else {
            return keyA > keyB ? 1 : -1;
        }
    });

    return sortArray.map(function(item) {
        const index = item[1];
        return items[index];
    });
}

function keyAlpha(colIndex) {
    return function(elem) {
        return elem.childNodes[1].childNodes[colIndex].firstChild.data.toLowerCase();
    };
}

function keyLink(colIndex) {
    return function(elem) {
        const dataCell = elem.childNodes[1].childNodes[colIndex].firstChild;
        return dataCell == null ? '' : dataCell.innerText.toLowerCase();
    };
}

function keyResult(colIndex) {
    return function(elem) {
        const strings = ['Error', 'Failed', 'Rerun', 'XFailed', 'XPassed',
            'Skipped', 'Passed'];
        return strings.indexOf(elem.childNodes[1].childNodes[colIndex].firstChild.data);
    };
}

function resetSortHeaders() {
    findAll('.sort-icon').forEach(function(elem) {
        elem.parentNode.removeChild(elem);
    });
    findAll('.sortable').forEach(function(elem) {
        const icon = document.createElement('div');
        icon.className = 'sort-icon';
        icon.textContent = 'vvv';
        elem.insertBefore(icon, elem.firstChild);
        elem.classList.remove('desc', 'active');
        elem.classList.add('asc', 'inactive');
    });
}

function toggleSortStates(elem) {
    //if active, toggle between asc and desc
    if (elem.classList.contains('active')) {
        elem.classList.toggle('asc');
        elem.classList.toggle('desc');
    }

    //if inactive, reset all other functions and add ascending active
    if (elem.classList.contains('inactive')) {
        resetSortHeaders();
        elem.classList.remove('inactive');
        elem.classList.add('active');
    }
}

function isAllRowsHidden(value) {
    return value.hidden == false;
}

function filterTable(elem) { // eslint-disable-line no-unused-vars
    const outcomeAtt = 'data-test-result';
    const outcome = elem.getAttribute(outcomeAtt);
    const classOutcome = outcome + ' results-table-row';
    const outcomeRows = document.getElementsByClassName(classOutcome);

    for(let i = 0; i < outcomeRows.length; i++){
        outcomeRows[i].hidden = !elem.checked;
    }

    const rows = findAll('.results-table-row').filter(isAllRowsHidden);
    const allRowsHidden = rows.length == 0 ? true : false;
    const notFoundMessage = document.getElementById('not-found-message');
    notFoundMessage.hidden = !allRowsHidden;
}
</script>
    <h1>自定义接口测试报告名称</h1>
    <p>Report generated on 15-Mar-2022 at 19:28:48 by <a href="https://pypi.python.org/pypi/pytest-html">pytest-html</a> v3.1.1</p>
    <h2>Environment</h2>
    <table id="environment">
      <tr>
        <td>JAVA_HOME</td>
        <td>C:\Program Files\Java\jdk1.8.0_281</td></tr>
      <tr>
        <td>Python版本</td>
        <td>3.7.3</td></tr>
      <tr>
        <td>包</td>
        <td>Requests(2.27.1)，PyMySQL(1.0.2)，Pandas(1.3.5)，Pytest(7.1.0)，Pytest-html(3.1.1)</td></tr>
      <tr>
        <td>平台</td>
        <td>Windows-10-10.0.19041-SP0</td></tr>
      <tr>
        <td>项目名称</td>
        <td>自定义项目名称</td></tr></table>
    <h2>Summary</h2>
    <p>7 tests ran in 0.24 seconds. </p>
    <p class="filter" hidden="true">(Un)check the boxes to filter the results.</p><input checked="true" class="filter" data-test-result="passed" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="passed">6 passed</span>, <input checked="true" class="filter" data-test-result="skipped" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="skipped">0 skipped</span>, <input checked="true" class="filter" data-test-result="failed" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="failed">1 failed</span>, <input checked="true" class="filter" data-test-result="error" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="error">0 errors</span>, <input checked="true" class="filter" data-test-result="xfailed" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="xfailed">0 expected failures</span>, <input checked="true" class="filter" data-test-result="xpassed" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="xpassed">0 unexpected passes</span>
    <h2>Results</h2>
    <table id="results-table">
      <thead id="results-table-head">
        <tr>
          <th class="sortable result initial-sort" col="result">Result</th>
          <th>测试描述</th>
          <th class="sortable" col="name">Test</th>
          <th class="sortable" col="duration">Duration</th></tr>
        <tr hidden="true" id="not-found-message">
          <th colspan="4">No results found. Try to check the filters</th></tr></thead>
      <tbody class="failed results-table-row">
        <tr>
          <td class="col-result">Failed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_06:测试密码错误-http://192.168.196.128:80/apitest/login/-post-data-args5-expect5]</td>
          <td class="col-duration">0.00</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"><span class="error">E   AssertionError: login_06:测试密码错误==响应结果比对失败==预期：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;用户名或密码错误&#x27;}==实际：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;密码错误&#x27;}</span><br/>    assert False<br/> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test04&#x27;, &#x27;password&#x27;: &#x27;123&#x27;}成功&#x27;)
WARNING:root:login_06:测试密码错误==响应结果比对失败==预期：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;用户名或密码错误&#x27;}==实际：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;密码错误&#x27;}
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:48 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test04&#x27;, &#x27;password&#x27;: &#x27;123&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:48 [WARNING] login_06:测试密码错误==响应结果比对失败==预期：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;用户名或密码错误&#x27;}==实际：{&#x27;Status&#x27;: 1004, &#x27;Result&#x27;: &#x27;Password error&#x27;, &#x27;Message&#x27;: &#x27;密码错误&#x27;} [case.py:60]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_01:测试登录成功-http://192.168.196.128:80/apitest/login/-post-data-args0-expect0]</td>
          <td class="col-duration">0.12</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> -----------------------------Captured stderr setup------------------------------ <br/>INFO:root:接口服务器信息：http://192.168.196.128:80==数据库服务器信息：{&#x27;host&#x27;: &#x27;192.168.196.128&#x27;, &#x27;db&#x27;: &#x27;wa_test&#x27;, &#x27;user&#x27;: &#x27;root&#x27;, &#x27;passwd&#x27;: &#x27;123456&#x27;}
INFO:root:连接数据库{&#x27;host&#x27;: &#x27;192.168.196.128&#x27;, &#x27;db&#x27;: &#x27;wa_test&#x27;, &#x27;user&#x27;: &#x27;root&#x27;, &#x27;passwd&#x27;: &#x27;123456&#x27;}成功
INFO:root:读sql语句文件(&#x27;login.sql&#x27;,)成功
INFO:root:初始化数据库(&#x27;login.sql&#x27;,)成功
<br/> -------------------------------Captured log setup------------------------------- <br/>2022-03-15 19:28:47 [INFO] 接口服务器信息：http://192.168.196.128:80==数据库服务器信息：{&#x27;host&#x27;: &#x27;192.168.196.128&#x27;, &#x27;db&#x27;: &#x27;wa_test&#x27;, &#x27;user&#x27;: &#x27;root&#x27;, &#x27;passwd&#x27;: &#x27;123456&#x27;} [conf.py:33]
2022-03-15 19:28:47 [INFO] 连接数据库{&#x27;host&#x27;: &#x27;192.168.196.128&#x27;, &#x27;db&#x27;: &#x27;wa_test&#x27;, &#x27;user&#x27;: &#x27;root&#x27;, &#x27;passwd&#x27;: &#x27;123456&#x27;}成功 [db.py:35]
2022-03-15 19:28:47 [INFO] 读sql语句文件(&#x27;login.sql&#x27;,)成功 [db.py:22]
2022-03-15 19:28:47 [INFO] 初始化数据库(&#x27;login.sql&#x27;,)成功 [db.py:47]<br/> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test01&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;)
INFO:root:login_01:测试登录成功==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:47 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test01&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:47 [INFO] login_01:测试登录成功==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_02:测试用户名为空-http://192.168.196.128:80/apitest/login/-post-data-args1-expect1]</td>
          <td class="col-duration">0.00</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;)
INFO:root:login_02:测试用户名为空==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:47 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:47 [INFO] login_02:测试用户名为空==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_03:测试密码为空-http://192.168.196.128:80/apitest/login/-post-data-args2-expect2]</td>
          <td class="col-duration">0.00</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test02&#x27;, &#x27;password&#x27;: &#x27;&#x27;}成功&#x27;)
INFO:root:login_03:测试密码为空==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:47 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test02&#x27;, &#x27;password&#x27;: &#x27;&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:47 [INFO] login_03:测试密码为空==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_04:测试用户名和密码均为空-http://192.168.196.128:80/apitest/login/-post-data-args3-expect3]</td>
          <td class="col-duration">0.00</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;&#x27;, &#x27;password&#x27;: &#x27;&#x27;}成功&#x27;)
INFO:root:login_04:测试用户名和密码均为空==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:48 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;&#x27;, &#x27;password&#x27;: &#x27;&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:48 [INFO] login_04:测试用户名和密码均为空==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_05:测试用户名错误-http://192.168.196.128:80/apitest/login/-post-data-args4-expect4]</td>
          <td class="col-duration">0.02</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test03&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;)
INFO:root:login_05:测试用户名错误==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:48 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test03&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:48 [INFO] login_05:测试用户名错误==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody>
      <tbody class="passed results-table-row">
        <tr>
          <td class="col-result">Passed</td>
          <td>None</td>
          <td class="col-name">testcase/login.py::test_login[login_07:测试用户名和密码均错误-http://192.168.196.128:80/apitest/login/-post-data-args6-expect6]</td>
          <td class="col-duration">0.01</td></tr>
        <tr>
          <td class="extra" colspan="4">
            <div class="log"> ------------------------------Captured stderr call------------------------------ <br/>INFO:root:执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test05&#x27;, &#x27;password&#x27;: &#x27;123&#x27;}成功&#x27;)
INFO:root:login_07:测试用户名和密码均错误==响应结果比对通过
<br/> -------------------------------Captured log call-------------------------------- <br/>2022-03-15 19:28:48 [INFO] 执行requests.post(&#x27;http://192.168.196.128:80/apitest/login/,data={&#x27;username&#x27;: &#x27;test05&#x27;, &#x27;password&#x27;: &#x27;123&#x27;}成功&#x27;) [case.py:39]
2022-03-15 19:28:48 [INFO] login_07:测试用户名和密码均错误==响应结果比对通过 [case.py:56]<br/></div></td></tr></tbody></table></body></html>